<template>
  <el-row>
    <el-alert type="info" show-icon>
      <template #title>
        <el-text size="small">当前展示的物模型是已发布到线上的版本 {{versionTip}}，如需修改，请点击 </el-text>
        <el-text size="small" type="primary" class="cursor" @click="viewDraft">编辑草稿</el-text>
      </template>
    </el-alert>
  </el-row>
  <el-row>
    <el-button type="primary" icon="el-icon-pointer" @click="viewDraft">前往编辑草稿</el-button>
    <el-tooltip
      class="item"
      effect="dark"
      content="查看物模型的 TSL(Thing Specification Language) 描述语言"
      placement="top"
    >
      <el-button @click="openTsl">物模型 TSL</el-button>
    </el-tooltip>
    <el-tooltip
      class="item"
      effect="dark"
      content="将JSON格式的物模型配置读取并导出"
      placement="top"
    >
      <el-button @click="exportTsl">物模型 导出</el-button>
    </el-tooltip>
<!--    <el-button>配置时序存储</el-button>-->
  </el-row>
  <el-row>
    <avue-crud ref="crud"
               :option="option"
               :data="data"
               v-model="form"
               :table-loading="loading"
               :before-open="beforeOpen"
               :before-close="beforeClose"
               @on-load="onLoad">
      <template #functionType="{ row }">
        <el-tag style="cursor: pointer">{{ row.functionTypeName }}</el-tag>
      </template>
      <template #specEnum-form="{}">
        <function-enum v-model="enumsData" :snapshot-mode="snapshotMode"></function-enum>
      </template>
      <template #specStruct-form="{}">
        <function-struct v-model="structData" :snapshot-mode="snapshotMode"></function-struct>
      </template>
      <template #specInput-form="{}">
        <function-struct-full v-model="inputData" :snapshot-mode="snapshotMode"></function-struct-full>
      </template>
      <template #specOutput-form="{}">
        <function-struct-full v-model="outputData" :snapshot-mode="snapshotMode"></function-struct-full>
      </template>
    </avue-crud>
    <el-dialog v-model="visibleTsl" :before-close="beforeCloseTsl" title="物模型" width="600">
      <el-row>
        <el-alert
            title="物模型是云端对设备功能的抽象描述，涵盖了设备的属性、服务和事件。物联网平台通过物的描述语言，即 TSL（Thing Specification Language），以 JSON 格式表达这一模型。开发者可以利用 TSL 构建并上报设备数据。完整的物模型可用于云端应用的开发，而精简版的物模型则可结合设备端SDK用于设备的开发工作。"
            type="info" :closable="false"/>
      </el-row>
      <el-row>
        <code-editor v-model="tsl" :json="true" :readonly="true" theme="nord"/>
      </el-row>
    </el-dialog>
  </el-row>
</template>

<script>
import {getDetail} from "@/api/iot/category";
import {validatenull} from "@/utils/validate";
import {dataTypeName, fieldTypeName, option} from "@/option/iot/function";
import {dataPublished, dataPublishedTsl} from "@/api/iot/category/version";
import func from "@/utils/func";
import { exportBlob } from '@/api/common';
import { downloadJson } from '@/utils/util';

export default {
  name: 'categoryFunction',
  props: {
    categoryId: String,
  },
  data() {
    return {
      form: {},
      tsl: "",
      detail: {},
      query: {},
      search: {},
      loading: false,
      visible: false,
      visibleTsl: false,
      versionId: "",
      versionTip: "",
      versionSelect: [],
      snapshotMode: true,
      option: option(this),
      formBlock: {},
      formTree: {},
      formVersion: "",
      data: [],
      structData: [],
      enumsData: [],
      inputData: [],
      outputData: [],
      dataSnapshot: {},
      functionSnapshot: [],
    };
  },
  mounted() {
    this.snapshotOperation();
  },
  created() {
    this.init();
  },
  methods: {
    init() {
      getDetail(this.categoryId).then(res => {
        this.detail = res.data.data;
        this.onLoad();
      });
      dataPublishedTsl(this.categoryId).then(res => {
        this.tsl = JSON.stringify(res.data.data);
      });
    },
    snapshotOperation() {
      this.$refs.crud.option.header = false;
      this.$refs.crud.option.editBtn = false;
      this.$refs.crud.option.delBtn = false;
      this.$refs.crud.option.viewBtn = true;
    },
    viewDraft() {
      const key = this.categoryId;
      this.$router.push({
        path: `/iot/category/draft/${key}`,
      });
    },
    transForm(row) {
      // 功能类型
      const functionType = this.form?.functionType;
      if (functionType === 2) {
        // 输入参数
        this.inputData = row.specInput;
        // 输出参数
        this.outputData = row.specOutput;
      }
      if (functionType === 3) {
        // 输出参数
        this.outputData = row.specOutput;
      }
      // 属性功能
      if (functionType === 1) {
        if (row.specFunction.fieldType === "enum") {
          // 枚举数据
          this.enumsData = func.keyValueToJsonArray(row.specFunction.specEnum);
        }
        if (row.specFunction.fieldType === "struct") {
          // 属性结构体
          this.structData = row.specFunction.specStruct;
        }
        row.specFunctionId = row.specFunction.id; // 功能主键
        row.fieldType = row.specFunction.fieldType; // 数据类型
        row.specMin = row.specFunction.specMin; // 最小值
        row.specMax = row.specFunction.specMax; // 最大值
        row.specStep = row.specFunction.specStep; // 步长
        row.specUnit = row.specFunction.specUnit; // 单位
        row.specEnum = row.specFunction.specEnum; // 枚举数据
        row.specBoolFalse = row.specFunction.specBoolFalse; // 布尔值 0
        row.specBoolTrue = row.specFunction.specBoolTrue; // 布尔值 1
        row.specLength = row.specFunction.specLength; // 数据长度
        row.specDateFormat = row.specFunction.specDateFormat; // 时间格式
        row.specItemType = row.specFunction.specItemType; // 元素类型
        row.specSize = row.specFunction.specSize; // 元素个数

      }
      return row;
    },
    beforeOpen(done, type) {
      if (["view"].includes(type)) {
        const data = this.functionSnapshot.find(item => item.id === this.form.id);
        this.form = this.transForm(data);
        if (data.functionType === 1) {
          this.form.fieldType = data.specFunction.fieldType;
          this.form.specFunctionId = data.specFunction.id;
        }
      }
      done();
    },
    beforeClose(done) {
      this.form = {};
      this.structData = [];
      this.enumsData = [];
      this.inputData = [];
      this.outputData = [];
      done();
    },
    openTsl() {
      this.visibleTsl = true;
    },
    exportTsl() {
      this.$confirm('是否导出物模型？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }).then(() => {
        exportBlob(
          `/blade-iot/category/version/tsl-export?categoryId=${this.categoryId}`
        ).then(res => {
          downloadJson(res.data, `category_tsl_${this.detail.categoryName}_${this.categoryId}_v${this.dataSnapshot.profile.versionNo}.json`);
        });
      });
    },
    beforeCloseTsl() {
      this.visibleTsl = false;
    },
    onLoad() {
      const categoryId = this.categoryId;
      if (validatenull(categoryId)) {
        return;
      }
      dataPublished(categoryId).then(res => {
        this.dataSnapshot = res.data.data;
        if (validatenull(this.dataSnapshot.profile)) {
          return;
        }
        this.versionTip = `v${this.dataSnapshot.profile.versionNo} (${this.dataSnapshot.profile.versionDate})`;
        // 将三个列表合并返回
        const properties = this.dataSnapshot.properties;
        const commands = this.dataSnapshot.commands;
        const events = this.dataSnapshot.events;
        // 设置功能列表快照
        this.functionSnapshot = [...properties, ...commands, ...events];
        this.data = this.functionSnapshot.map(item => {
          return {
            ...item,
            fieldTypeName: fieldTypeName(item),
            dataTypeName: dataTypeName(item)
          }
        });
      });
    },
  }
};
</script>

<style>
.el-row {
  margin-bottom: 20px;
}

.el-row:last-child {
  margin-bottom: 0;
}

.cursor {
  cursor: pointer;
}
</style>
